package thread;

import java.util.ArrayList;
import java.util.List;

/**
 * 多生产者多消费者模型
 */
public class MultipleProductAndConsumer {
    public static void main(String[] args) throws InterruptedException {
        
        Box box=new Box();
        ProductService productService=new ProductService(box);
        ConsumerService consumerService=new ConsumerService(box);
        
        Thread p1=new ProductThread(productService);
        Thread p1c=new ProductCheckBoxThread(productService);
        Thread p2=new ProductThread(productService);
        p1.start();
        p1c.start();
        p2.start();

        Thread.sleep(3000);

        Thread c1=new ConsumerThread(consumerService);
        Thread c1c=new ConsumerCheckBoxThread(consumerService);
        Thread c2=new ConsumerThread(consumerService);
        c1.start();
        c1c.start();
        c2.start();


        
    }
}

/**
 * 任务队列
 */
class Box {
    private static List list = new ArrayList();

    synchronized public void add() {
        if (list.size() < 50) {
            list.add("anyString");
            System.out.println("线程" + Thread.currentThread().getName() + "执行add()方法，size=" + size());
        }
    }

    synchronized public int size() {
        return list.size();
    }

    synchronized public Object popFirst() {
        Object value = list.remove(0);
        System.out.println("线程" + Thread.currentThread().getName() + "执行popFirst()方法，size=" + size());
        return value;
    }

}

/**
 * 生产者
 */
class ProductService {

    private Box box;

    ProductService(Box box) {
        this.box = box;
    }

    /**
     * 生产者方法
     */
    public void setMethod() {
        try {
            synchronized (this) {
                while (box.size() == 50) {
                    System.out.println(" ●●●●●●");
                    this.wait();
                }
                box.add();
            }
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /**
     * 检测任务队列，任务过少时唤醒生产者
     */
    public void checkBoxStatus() {
        try {
          while (true){
              synchronized (this) {
                  if (box.size() < 150) {
                      this.notifyAll();
                  }
              }
              System.out.println("set checkboxBox ="+box.size());
              Thread.sleep(1000);
          }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }



}

/**
 * 生产者线程
 */
class ProductThread extends  Thread{

    private ProductService productService;

    ProductThread(ProductService productService){
        this.productService=productService;
    }

    @Override
    public void run() {
        while (true){
            productService.setMethod();
        }

    }
}
/**
 * 生产者队列监测线程
 */
class ProductCheckBoxThread extends Thread{

    private ProductService productService;

    ProductCheckBoxThread(ProductService productService){
        this.productService=productService;
    }

    @Override
    public void run() {
        productService.checkBoxStatus();
    }
}




/**
 * 消费者
 */
class ConsumerService {

    private Box box;

    ConsumerService(Box box) {
        this.box = box;
    }

    /**
     * 消费者方法
     */
    public void getMethod() {
        try {
            synchronized (this) {
                while (box.size() == 0) {
                    System.out.println(" ○○○○○○○○○");
                    this.wait();
                } 
                box.popFirst(); 
            }
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    /**
     * 检测任务队列，有任务时唤起消费者消费
     */
    public void checkBoxStatus() {
        try {
            while (true){
                synchronized (this) {
                    if (box.size()> 0) {
                        this.notifyAll();
                    }
                    Thread.sleep(1000);
                }
                System.out.println("get checkboxBox ="+box.size());
                Thread.sleep(1000);
            }

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }



}


/**
 * 消费者线程
 */
class ConsumerThread extends  Thread{

    private ConsumerService consumerService;

    ConsumerThread(ConsumerService consumerService){
        this.consumerService=consumerService;
    }

    @Override
    public void run() {
        while (true){
            consumerService.getMethod();
        }

    }
}
/**
 * 生产者队列监测线程
 */
class ConsumerCheckBoxThread extends Thread{

    private ConsumerService consumerService;

    ConsumerCheckBoxThread(ConsumerService consumerService){
        this.consumerService=consumerService;
    }

    @Override
    public void run() {
        consumerService.checkBoxStatus();
    }
}

